/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace DaveSexton.DocProject.DocSites
{
	public struct IndexEntry : IEquatable<IndexEntry>
	{
		#region Public Properties
		public string Name
		{
			get
			{
				return System.IO.Path.GetFileName(file);
			}
		}

		public string VirtualPath
		{
			get
			{
				Uri root = new Uri(HttpContext.Current.Request.PhysicalApplicationPath);
				string virtualPath = HttpUtility.UrlDecode(root.MakeRelativeUri(new Uri(file)).ToString());

				return virtualPath;
			}
		}

		public string File { get { return file; } }

		public string Title { get { return title; } }

		/// <summary>
		/// Gets the number of times the keyword related to this entry was found in the <see cref="File"/>.
		/// </summary>
		public int Occurrences { get { return occurrences; } }

		/// <summary>
		/// Gets the relative weight of this entry's related keyword compared to the other keywords found in the same <see cref="File"/>.
		/// </summary>
		/// <value>The relative keyword weight is usually a factor of the positions at which the keyword was found in the <see cref="File"/>.  
		/// Keywords found earlier in the file will have a higher weight than others.  This value is usually the total of the factors of 
		/// all positions for the related keyword.</value>
		public int Weight { get { return weight; } }

		public MSHelpEntry MSHelp { get { return msHelp; } }
		#endregion

		#region Private / Protected
		private readonly string file, title;
		private readonly int occurrences, weight;
		private readonly MSHelpEntry msHelp;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="IndexEntry" /> structure.
		/// </summary>
		public IndexEntry(string title, string file, MSHelpEntry msHelp)
		{
			this.title = title;
			this.file = file;
			this.msHelp = msHelp;
			occurrences = 0;
			weight = 0;
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="IndexEntry" /> structure.
		/// </summary>
		public IndexEntry(string title, string file, MSHelpEntry msHelp, int occurrences)
		{
			this.title = title;
			this.file = file;
			this.msHelp = msHelp;
			this.occurrences = occurrences;
			weight = 0;
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="IndexEntry" /> structure.
		/// </summary>
		public IndexEntry(string title, string file, MSHelpEntry msHelp, int occurrences, int weight)
		{
			this.title = title;
			this.file = file;
			this.msHelp = msHelp;
			this.occurrences = occurrences;
			this.weight = weight;
		}
		#endregion

		#region Methods
		public IndexEntry IncrementOccurrences(int addOccurrences)
		{
			return new IndexEntry(title, file, msHelp, occurrences + addOccurrences, weight);
		}

		public IndexEntry IncrementWeight(int addWeight)
		{
			return new IndexEntry(title, file, msHelp, occurrences, weight + addWeight);
		}

		public IndexEntry IncrementOccurrencesAndWeight(int addOccurrences, int addWeight)
		{
			return new IndexEntry(title, file, msHelp, occurrences + addOccurrences, weight + addWeight);
		}

		public override string ToString()
		{
			return title;
		}

		public override bool Equals(object obj)
		{
			if (obj is IndexEntry)
				return Equals((IndexEntry) obj);
			else
				return base.Equals(obj);
		}

		public override int GetHashCode()
		{
			return (file ?? "").GetHashCode();
		}

		public static bool operator ==(IndexEntry entry1, IndexEntry entry2)
		{
			return entry1.Equals(entry2);
		}

		public static bool operator !=(IndexEntry entry1, IndexEntry entry2)
		{
			return !entry1.Equals(entry2);
		}
		#endregion

		#region IEquatable<IndexEntry> Members
		public bool Equals(IndexEntry other)
		{
			return string.Equals(other.file, file, StringComparison.OrdinalIgnoreCase);
		}
		#endregion
	}
}
